# -*- coding: utf-8 -*-
from sqlalchemy import func
from dao.db import db
from datetime import datetime
from sqlalchemy.ext.hybrid import hybrid_property

class Exam(db.Model):
    __tablename__ = 'exams'

    id = db.Column(db.BigInteger, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    class_id = db.Column(db.BigInteger, db.ForeignKey('classes.id'))
    grade = db.Column(db.Integer)
    deadline = db.Column(db.DateTime, nullable=False)
    created_by = db.Column(db.BigInteger, db.ForeignKey('teachers.id'), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.now)
    display_grade = db.Column(db.Integer)

    # 关系
    class_info = db.relationship('Class', backref='exams')
    creator = db.relationship('Teacher')

class Score(db.Model):
    __tablename__ = 'scores'

    id = db.Column(db.BigInteger, primary_key=True)
    exam_id = db.Column(db.BigInteger, db.ForeignKey('exams.id'), nullable=False)
    student_id = db.Column(db.BigInteger, db.ForeignKey('students.id'), nullable=False)
    _score = db.Column('score', db.Numeric(5, 2), nullable=True)

    # 关系
    exam = db.relationship('Exam', backref='scores')
    student = db.relationship('Student', backref='scores')

    # 唯一约束（防止重复录入成绩）
    __table_args__ = (
        db.UniqueConstraint('exam_id', 'student_id', name='uq_exam_student'),
        {'comment': '学生考试成绩表'}
    )

    @hybrid_property
    def score(self):
        """Python 访问时：返回保留两位小数的成绩"""
        if self._score is not None:
            return round(float(self._score), 2)
        return None

    @score.expression
    def score(cls):
        """SQL 查询时：返回 SQL 表达式"""
        return func.round(cls._score, 2)

    @score.setter
    def score(self, value):
        """设置成绩（自动处理小数位）"""
        if value is not None:
            try:
                # 限制最大 100 分
                if float(value) > 150:
                    raise ValueError("成绩不能超过 150")
                self._score = round(float(value), 2)
            except (ValueError, TypeError):
                raise ValueError("成绩必须是有效的数字")
        else:
            self._score = None